#if !defined(_CLIENTINTERFACE_)
#define _CLIENTINTERFACE_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// clientinterface.h : header file
//

// filename for the stored video local cantainer
#define	 STORED_VIDEO_FILENAME	"stored_video0.rms"

// message id to update socket status
#define	 WM_UPDATE_SESSION_STATUS	(WM_USER+444)
// message id to exit full screen mode
#define	 WM_FULL_SCREEN_EXIT		(WM_USER+445)

// socket status values
#define	 SOCKET_STATUS_UNDEFINED	0
#define	 OPENING_CONNECTION			1
#define	 CONNECTING					2
#define	 CONNECTED					3
#define	 RECEIVING					4
#define	 CLOSING_SOCKET				5
#define	 SESSION_ERROR				6
#define	 BAD_FORMAT					7
#define	 CONNECTION_REFUSED			8
#define	 CONNECTION_LOST			9
#define	 SENDING_REQUEST			10
#define	 UNABLE_TO_BUFFER_DATA		11
#define	 DISCONNECT					12
#define	 FINISH						13
#define	 CLOSING_CONNECTION			14
#define	 FAIL						15
#define	 DECLINE					16
#define	 NO_RECORDS					17
#define	 GET_RECORDS				18

// timer ids
#define	 TIMER_REFRESH_DATA			0
#define	 TIMER_RESET_STATUS			1
#define	 TIMER_WAIT_FOR_DATA		2
#define	 TIMER_TIMEOUT				12


class CVideoPlayer;
class CWaveSync;
class CSite;
class CChannelInfo;
class CInfo;


/////////////////////////////////////////////////////////////////////////////
// ClientInterface class - defines interface for RMS clients

class ClientInterface
{
// Operations
public:
	virtual void enterCritical() = 0;
	virtual void leaveCritical() = 0;

	virtual CWaveSync* getSessionWaveSocket(int camera = 0) = 0;
	virtual CVideoPlayer* getPlayer() = 0;
#ifdef _JNC_REC_
	virtual void returnRecords(BYTE* p, DWORD dwLen) = 0;
#endif //def _JNC_REC_

	virtual void showControlsOnDisconnect() = 0;

	virtual BYTE** getYComponent(int camera = 0) = 0;
	virtual BYTE** getUComponent(int camera = 0) = 0;
	virtual BYTE** getVComponent(int camera = 0) = 0;

	virtual HWND getWindow() = 0;

	virtual void setSessionTime(LPCTSTR time) = 0;
	virtual void setSessionDate(LPCTSTR date) = 0;
	virtual void setCameraInfo(int channel, CInfo& info) = 0;
	virtual void SetAudioStatus(int iStatus) = 0;

	virtual CSyncObject* getFileLock() = 0;
	virtual LRESULT OnConnectFailed(WPARAM wParam, LPARAM lParam) = 0;

	virtual map<CString, CSite>* getSitesLive() = 0;
	virtual map<CString, CSite>* getSitesStored() = 0;

	virtual CSite* getLiveSite(LPCTSTR site) = 0;
	virtual CSite* getStoredSite(LPCTSTR site) = 0;

	virtual CChannelInfo* getInfoLive(int channel = 0) = 0;
	virtual CChannelInfo* getInfoStored(int channel = 0) = 0;

	virtual int getActiveChannel() = 0;

	virtual void* getLivePage() = 0;
	virtual void* getStoredPage() = 0;

	virtual int sessionConnect(int camera = 0) = 0;
	virtual int sessionDisconnect(int camera = 0) = 0;

	virtual LPCTSTR getHomePath() = 0;
	virtual void saveHomePath(LPCTSTR name) = 0;
	virtual LPCTSTR getAudioDriverName() = 0;
	virtual void saveAudioDriverName(LPCTSTR name) = 0;

	virtual void mesOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList) = 0;
	virtual void mesOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...) = 0;
	virtual void warOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList) = 0;
	virtual void warOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...) = 0;
	virtual void errOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList) = 0;
	virtual void errOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...) = 0;

	virtual LPCTSTR getCallString(LPTSTR callStr, int maxlen) = 0;

	virtual BYTE* getDecoderMemory() = 0;
	virtual CEvent* getRefreshEvent() = 0;

	virtual DWORD getFrameSize() = 0;
	virtual BOOL getEnableRingFlag() = 0;

#ifdef _TEC_
	virtual BOOL isEncoderActive() = 0;
#endif //def _TEC_
};


/////////////////////////////////////////////////////////////////////////////
// ClientAccessLock class

class ClientAccessLock
{
	CRITICAL_SECTION* m_pcs;

public:
	ClientAccessLock(CRITICAL_SECTION* pcs)
	{
		m_pcs = pcs;
		EnterCriticalSection(m_pcs);
	};

	~ClientAccessLock()
	{
		LeaveCriticalSection(m_pcs);
	};
};


/////////////////////////////////////////////////////////////////////////////
// ClientAccess class

class ClientAccess : public ClientInterface
{
public:
	ClientAccess()
	{
		m_pClient = NULL;
		InitializeCriticalSection(&m_cs);
	};

	~ClientAccess()
	{
		{
			ClientAccessLock l(&m_cs);
			m_pClient = NULL;
		}
		DeleteCriticalSection(&m_cs);
	};

	ClientInterface* getClient()
	{
		return m_pClient;
	};

	virtual void setClient(ClientInterface* pclient)
	{
		ClientAccessLock l(&m_cs);
		m_pClient = pclient;
	};

protected:
	ClientInterface* m_pClient;
	CRITICAL_SECTION m_cs;

// Operations
public:
	void enterCritical()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->enterCritical();
	};

	void leaveCritical()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->leaveCritical();
	};

	CWaveSync* getSessionWaveSocket(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getSessionWaveSocket(camera);

		return NULL;
	};

	CVideoPlayer* getPlayer()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getPlayer();

		return NULL;
	};

#ifdef _JNC_REC_
	void returnRecords(BYTE* p, DWORD dwLen)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->returnRecords(p, dwLen);
	};
#endif //def _JNC_REC_

	void showControlsOnDisconnect()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->showControlsOnDisconnect();
	};

	BYTE** getYComponent(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getYComponent(camera);

		return NULL;
	};

	BYTE** getUComponent(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getUComponent(camera);

		return NULL;
	};

	BYTE** getVComponent(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getVComponent(camera);

		return NULL;
	};

	HWND getWindow()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getWindow();

		return NULL;
	};

	void setSessionTime(LPCTSTR time)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->setSessionTime(time);
	};

	void setSessionDate(LPCTSTR date)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->setSessionDate(date);
	};

	void setCameraInfo(int channel, CInfo& info)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->setCameraInfo(channel, info);
	};

	void SetAudioStatus(int iStatus)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->SetAudioStatus(iStatus);
	};

	CSyncObject* getFileLock()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getFileLock();

		return NULL;
	};

	LRESULT OnConnectFailed(WPARAM wParam, LPARAM lParam)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->OnConnectFailed(wParam, lParam);

		return 0;
	};

	map<CString, CSite>* getSitesLive()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getSitesLive();

		return NULL;
	};

	map<CString, CSite>* getSitesStored()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getSitesStored();

		return NULL;
	};

	CSite* getLiveSite(LPCTSTR site)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getLiveSite(site);

		return NULL;
	};

	CSite* getStoredSite(LPCTSTR site)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getStoredSite(site);

		return NULL;
	};

	CChannelInfo* getInfoLive(int channel = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getInfoLive(channel);

		return NULL;
	};

	CChannelInfo* getInfoStored(int channel = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getInfoStored(channel);

		return NULL;
	};

	int getActiveChannel()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getActiveChannel();

		return 0;
	};

	void* getLivePage()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getLivePage();

		return NULL;
	};

	void* getStoredPage()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getStoredPage();

		return NULL;
	};

	int sessionConnect(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->sessionConnect(camera);

		return 0;
	};

	int sessionDisconnect(int camera = 0)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->sessionDisconnect(camera);

		return 0;
	};

	LPCTSTR getHomePath()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getHomePath();

		return _T("");
	};

	void saveHomePath(LPCTSTR name)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->saveHomePath(name);
	};

	LPCTSTR getAudioDriverName()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getAudioDriverName();

		return _T("");
	};

	void saveAudioDriverName(LPCTSTR name)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->saveAudioDriverName(name);
	};

	void mesOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->mesOut(sFile, sLine, pFStr, aList);
	};

	void mesOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...)
	{
		va_list aList;
		va_start(aList, pFStr);
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->mesOut(sFile, sLine, pFStr, aList);
		va_end(aList);
	};

	void warOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->warOut(sFile, sLine, pFStr, aList);
	};

	void warOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...)
	{
		va_list aList;
		va_start(aList, pFStr);
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->warOut(sFile, sLine, pFStr, aList);
		va_end(aList);
	};

	void errOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, va_list aList)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->errOut(sFile, sLine, pFStr, aList);
	};

	void errOut(LPCTSTR sFile, int sLine, LPCTSTR pFStr, ...)
	{
		va_list aList;
		va_start(aList, pFStr);
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			m_pClient->errOut(sFile, sLine, pFStr, aList);
		va_end(aList);
	};

	LPCTSTR getCallString(LPTSTR callStr, int maxlen)
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getCallString(callStr, maxlen);

		return _T("");
	};

	BYTE* getDecoderMemory()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getDecoderMemory();

		return NULL;
	};

	CEvent* getRefreshEvent()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getRefreshEvent();

		return NULL;
	};

	DWORD getFrameSize()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getFrameSize();

		return 1;
	};

	BOOL getEnableRingFlag()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->getEnableRingFlag();

		return FALSE;
	};

#ifdef _TEC_
	BOOL isEncoderActive()
	{
		ClientAccessLock l(&m_cs);
		if(m_pClient)
			return m_pClient->isEncoderActive();

		return FALSE;
	};
#endif //def _TEC_
};

/////////////////////////////////////////////////////////////////////////////

#endif // !defined(_CLIENTINTERFACE_)
